package com.heima.leadnews.artlite.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.leadnews.artlite.mapper.ApArticleMapper;
import com.heima.leadnews.artlite.service.ApArticleConfigService;
import com.heima.leadnews.artlite.service.ApArticleContentService;
import com.heima.leadnews.artlite.service.ApArticleService;
import com.heima.model.common.article.dto.*;
import com.heima.model.common.article.pojo.ApArticle;
import com.heima.model.common.article.pojo.ApArticleConfig;
import com.heima.model.common.article.pojo.ApArticleContent;
import com.heima.model.common.article.vo.ApArticleVo;
import com.heima.model.common.article.vo.LoadArticleBehaviorVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.wemedia.dto.ContentSegment;
import com.heima.model.common.wemedia.dto.WmNewsADto;
import com.heima.utils.common.UserContext;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-05-31
 */
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    private  ApArticleMapper apArticleMapper;
    @Autowired
    private ApArticleContentService apArticleContentService;
    @Autowired
    private ApArticleConfigService apArticleConfigService;

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 点击某个频道，展示该频道最新的3个文章
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ApArticle>> load(ApArticleDto dto) {

        List<ApArticle> list = apArticleMapper.load(dto.getTag(), dto.getSize());
        return ResponseResult.okResult(list);
    }

    /**
     * 向上刷新频道，展示该频道最新的3个文章
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ApArticle>> loadMore(ApArticleMinDto dto) {
        List<ApArticle> list = apArticleMapper.loadmore(dto.getTag(), dto.getSize(), dto.getMinBehotTime());
        return ResponseResult.okResult(list);
    }

    /**
     * 向下刷新频道，展示该频道最新的3个文章
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ApArticle>> loadnew(ApArticleAMaxDto dto) {
        List<ApArticle> list = apArticleMapper.loadnew(dto.getTag(), dto.getSize(), dto.getMaxBehotTime());
        return ResponseResult.okResult(list);
    }

    /**
     * 保存用户端文章信息
     * 内部接口，被article调用
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveArticle(WmNewsADto dto) {

        //向文章基本信息表,配置表，内容表插入文章信息
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(dto,apArticle);
        apArticle.setAuthorId(dto.getUserId());
        apArticle.setLayout(dto.getType());
        apArticle.setFlag(0);
        apArticle.setLikes(0);
        apArticle.setCollection(0);
        apArticle.setComment(0);
        apArticle.setViews(0);
        save(apArticle);
        Long apArticleId = apArticle.getId();
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticleId);
        apArticleConfig.setIsComment(true);
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsDown(false);
        apArticleConfig.setIsDelete(false);
        apArticleConfigService.save(apArticleConfig);


        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticleId);
        apArticleContent.setContent(dto.getContent());
        apArticleContentService.save(apArticleContent);

        return ResponseResult.okResult(apArticleId);
    }

    /**
     * 更新文章详情页面地址
     * @return
     */
    @Override
    public ResponseResult updateStaticUrl(Long articleId, String url) {
        ApArticle apArticle = getById(articleId);
        if (apArticle==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
     apArticle.setStaticUrl(url);
        updateById(apArticle);
        return ResponseResult.okResult();
    }

    /**
     * 查询所有文章
     * 内部接口，被search服务远程调用
     * @return
     */
    @Override
    public ResponseResult<List<ArticleDocDto>> findAll() {
        List<ArticleDocDto> dtoList = apArticleMapper.findAll();
        for (ArticleDocDto articleDocDto : dtoList) {
            String content = getStringBuilder(articleDocDto.getContent());
            articleDocDto.setContent(content);
        }
        return ResponseResult.okResult(dtoList);
    }

    /**
     * 根据文章id 查询文章信息
     * 内部接口，被search服务远程调用
     * @return
     */
    @Override
    public ResponseResult<ArticleDocDto> findById(Long id) {
        ArticleDocDto docDto = apArticleMapper.fingById(id);
        String content = getStringBuilder(docDto.getContent());
        docDto.setContent(content);
        return ResponseResult.okResult(docDto);
    }
    /**
     * 5 加载文章行为-数据回显
     */
    @Override
    public ResponseResult<LoadArticleBehaviorVo> loadArticleBehavior(loadArticleBehaviorDto dto) {
        Long userId = UserContext.getUserId();
        LoadArticleBehaviorVo vo = new LoadArticleBehaviorVo();
        if (userId==null){
         return ResponseResult.okResult(vo);
        }
        //查询用户是否对文章点赞
        String key = "like:" + dto.getArticleId();
        Object o = redisTemplate.opsForHash().get(key, userId);
        if ( o.equals("0")){
            vo.setIslike(true);
        }
        // 查询用户是否对文章收藏
        // 查询用户是否对文章作者关注
        return ResponseResult.okResult(vo);
    }

    @Override
    public void saveHotArticle() {
        Date date = DateUtils.addDays(new Date(), -5);
        List<ApArticleVo> list = apArticleMapper.findHotArticle(date);
        Map<Integer, List<ApArticleVo>> listMap = list.stream().collect(Collectors.groupingBy(ApArticleVo::getChannelId));
        for (Integer channeId : listMap.keySet()) {
            List<ApArticleVo> hotArticleVo = listMap.get(channeId);
            List<ApArticleVo> voList = hotArticleVo.stream().limit(1).collect(Collectors.toList());
            String key = "hot" +channeId;
            redisTemplate.opsForValue().set(key,voList);
        }
      String key = "hot:_all_";
        redisTemplate.opsForValue().set(key,list.stream().limit(1).collect(Collectors.toList()));
    }
    /**
     *用户点击某个频道，展示该频道最新的10个热点文章
     */
    @Override
    public ResponseResult<List<ApArticleVo>> loadHotArtaic(String channelId) {
        String key = "hot"+channelId;
        List<ApArticleVo> list= (List<ApArticleVo>) redisTemplate.opsForValue().get(key);
        return ResponseResult.okResult(list);
    }

    private String getStringBuilder(String content) {
        List<ContentSegment> contentSegments = JSON.parseArray(content, ContentSegment.class);
        StringBuilder stringBuilder = new StringBuilder();
        for (ContentSegment contentSegment : contentSegments) {
            String type = contentSegment.getType();
            String value = contentSegment.getValue();
            if(type.equals("text")) {
                stringBuilder.append(value);
            }
        }
        return stringBuilder.toString();
    }
}
